using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using RuleID = ProjScan.ScanRuleFixer.Rule.ProjectAssets;

namespace ProjScan.ScanRuleFixer.Model
{
    public class ImportMaterialNone : IRuleFixer<RuleID.Model.ImportMaterialNone>
    {
        private string simpleMatPath = "Assets/GameFramework/Resources/Materials/Simple.mat";

        public bool Fix(string assetPath)
        {
            var simpleMaterial = GetOrCreateSimpleMat();
            var modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter;

            if (simpleMaterial == null)
            {
                Debug.LogError($"找不到框架中 simple 材质球 {simpleMatPath}");
                return false;
            }

            if (modelImporter == null)
            {
                Debug.LogError($"找不到需要被修复的资源 : {assetPath}");
                return false;
            }

            if (modelImporter.materialImportMode != ModelImporterMaterialImportMode.ImportStandard)
            {
                modelImporter.materialImportMode = ModelImporterMaterialImportMode.ImportStandard;
            }

            if (modelImporter.materialLocation != ModelImporterMaterialLocation.InPrefab)
            {
                modelImporter.materialLocation = ModelImporterMaterialLocation.InPrefab;
            }

            bool needsProcessing = false;
            var assetGameObject = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);

            var externalObjectMap = modelImporter.GetExternalObjectMap();
            if (assetGameObject != null)
            {
                var renderers = assetGameObject.GetComponentsInChildren<Renderer>();

                var sourceIdentifiers = new List<AssetImporter.SourceAssetIdentifier>();
                
                foreach (var renderer in renderers)
                {
                    if (renderer.sharedMaterials == null) continue;

                    foreach (var sharedMat in renderer.sharedMaterials)
                    {
                        if (sharedMat != null)
                        {
                            var sourceIdentifier = new AssetImporter.SourceAssetIdentifier
                            {
                                name = sharedMat.name,
                                type = typeof(Material)
                            };
                            sourceIdentifiers.Add(sourceIdentifier);
                        }
                    }
                }

                foreach (var sourceId in sourceIdentifiers)
                {
                    if (!externalObjectMap.TryGetValue(sourceId, out UnityEngine.Object mappedObj))
                    {
                        needsProcessing = true;
                    }
                    else
                    {
                        if (mappedObj != simpleMaterial)
                        {
                            needsProcessing = true;
                        }
                    }

                    modelImporter.AddRemap(sourceId, simpleMaterial);
                }
            }

            if (!needsProcessing)
            {
                foreach (var mapping in externalObjectMap)
                {
                    var key = mapping.Key;
                    modelImporter.AddRemap(key, simpleMaterial);
                }
            }

            modelImporter.SearchAndRemapMaterials(ModelImporterMaterialName.BasedOnMaterialName,
                ModelImporterMaterialSearch.RecursiveUp);
            AssetDatabase.WriteImportSettingsIfDirty(assetPath);
            AssetDatabase.Refresh();
            return true;
        }

        Material GetOrCreateSimpleMat()
        {
            var mat = AssetDatabase.LoadAssetAtPath<Material>(simpleMatPath);

            // 检查目录是否存在
            string materialFolder = Path.GetDirectoryName(simpleMatPath);
            if (!Directory.Exists(materialFolder))
            {
                Directory.CreateDirectory(materialFolder);
            }

            if (mat == null)
            {
                var shader = Shader.Find("Unlit/Color");
                if (shader == null)
                {
                    shader = Shader.Find("Unlit/Texture");
                }

                if (shader == null)
                {
                    Debug.LogError("错误，找不到shader");
                }

                mat = new Material(shader);

                AssetDatabase.CreateAsset(mat, simpleMatPath);
                AssetDatabase.SaveAssets();
            }

            return mat;
        }
    }
}